package io.netty.example.study.server.codec.handler;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.example.study.common.Operation;
import io.netty.example.study.common.OperationResult;
import io.netty.example.study.common.RequestMessage;
import io.netty.example.study.common.ResponseMessage;
import lombok.extern.slf4j.Slf4j;

/**
 * Handler 处理的是二次解码器解码后的业务数据结构 RequestMessage；
 * SimpleChannelInboundHandler#channelRead 应用了模板方法模式，其中有释放 ByteBuf 的逻辑，
 * 因此只需重写模板方法 channelRead0 完成业务逻辑即可；
 * OrderServerProcessHandler 与 2 个解码器、 2 个 编码器构成了 1 + 4 的结构；
 */
@Slf4j
public class OrderServerProcessHandler extends SimpleChannelInboundHandler<RequestMessage> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RequestMessage requestMessage) throws Exception {

        // 如果 leakBuffer 没有 release 的话，就会发生内存泄漏；
        // 用于测试内存泄漏的代码，不属于项目代码
        // TODO: 2020/2/27 项目正常启动时要删除下面这行代码，测试用客户端 CLientV3；
//        ByteBuf leakBuffer = ctx.alloc().buffer();

        Operation operation = requestMessage.getMessageBody();
        OperationResult operationResult = operation.execute();

        ResponseMessage responseMessage = new ResponseMessage();
        responseMessage.setMessageHeader(requestMessage.getMessageHeader());
        responseMessage.setMessageBody(operationResult);

        // 这是对设置的高低水位线参数的尊重，如果设置了高低水位线，这里却不做判断，直接写，就有可能 OOM；
        if (ctx.channel().isActive() && ctx.channel().isWritable()) {
            ctx.writeAndFlush(responseMessage);
        } else {
            log.error("message dropped");
        }

    }

}
